package grow

import (
	"github.com/hwcer/cosgo/random"
	"github.com/hwcer/cosgo/registry"
	"github.com/hwcer/cosgo/slice"
	"github.com/hwcer/yyds/context"
	"github.com/hwcer/yyds/errors"
	"server/game/cache"
	"server/game/model"
	"server/share/config"
	"strconv"
	"strings"
)

func init() {
	Register(&star{})
}

/**
 * @name star
 * 流星
 */

type star struct {
}

func (this *star) Caller(node *registry.Node, handle *context.Context) interface{} {
	f := node.Method().(func(*star, *context.Context) interface{})
	return f(this, handle)
}

/**
 * @name getStar
 * 获取流星数据
 */
func (this *star) GetStar(c *context.Context) any {
	roleDoc := cache.GetRole(c.Player.Updater)
	roleData := roleDoc.All()
	starData, change := roleData.GetStar(c.Now())
	if change {
		roleDoc.Set("Star", starData)
	}
	return starData
}

/**
 * @name useStar
 * @param int starID 流星ID
 * 使用流星
 */
func (this *star) UseStar(c *context.Context) any {
	starID := c.GetInt32("starID")
	roleDoc := cache.GetRole(c.Player.Updater)
	roleData := roleDoc.All()
	starData, _ := roleData.GetStar(c.Now())
	if starID < 0 || int(starID) >= len(starData.List) {
		return errors.ErrArgEmpty
	}
	i := slice.IndexOf(starData.List, starID)
	if i < 0 {
		return c.Errorf(0, "没有找到流星:%d", starID)
	}
	id := starData.List[i]
	starData.List = append(starData.List[:i], starData.List[i+1:]...)
	roleDoc.Set("Star", starData)
	starBuff, change := roleData.GetStarBuff(c.Now())
	meteorEffect := config.Data.MeteorEffect[id]
	if meteorEffect == nil {
		return c.Errorf(0, "流星效果配置不存在:%d", id)
	}
	now := c.Milli()
	for _, k := range meteorEffect.BuffGroup {
		starBuffConfig := config.Data.StarBuff[k]
		if starBuffConfig == nil {
			continue
		}
		switch strings.ToUpper(starBuffConfig.BuffEffect) {
		case "ITEM":
			iid, _ := strconv.Atoi(starBuffConfig.Val)
			if iid <= 0 {
				return c.Errorf(0, "<UNK>:%s", starBuffConfig.Val)
			}
			if num := random.Roll(starBuffConfig.RandomMin, starBuffConfig.RandomMax); num > 0 {
				c.Player.Add(int32(iid), num)
			}
		case "BUFF":
			change = true
			starBuff.Buff = append(starBuff.Buff, model.RoleStarBuffItem{
				Val:       starBuffConfig.Val,
				IfPercent: starBuffConfig.IfPercent,
				Field:     starBuffConfig.Field,
				RandomVal: random.Roll(starBuffConfig.RandomMin, starBuffConfig.RandomMax),
				BeginTime: now,
				EndTime:   now + int64(random.Roll(starBuffConfig.TimeMin, starBuffConfig.TimeMax))*1000,
			})
		case "ITEMBUFF":
			change = true
			starBuff.Item = append(starBuff.Buff, model.RoleStarBuffItem{
				Val:       starBuffConfig.Val,
				IfPercent: starBuffConfig.IfPercent,
				RandomVal: random.Roll(starBuffConfig.RandomMin, starBuffConfig.RandomMax),
				BeginTime: now,
				EndTime:   now + int64(random.Roll(starBuffConfig.TimeMin, starBuffConfig.TimeMax))*1000,
			})
		case "MONSTER":
			iid, _ := strconv.Atoi(starBuffConfig.Val)
			if iid <= 0 {
				return c.Errorf(0, "<UNK>:%s", starBuffConfig.Val)
			}
			waveConfig := config.Data.Wave[int32(iid)]
			if waveConfig == nil {
				return c.Errorf(0, "Wave Config:%d", iid)
			}

		}
	}
	if change {
		roleDoc.Set("StarBuff", starBuff)
	}
	return nil
}

/**
 * @name killStarMonster
 * @param int waveID 波叔ID
 * @param int monsterID 怪物ID
 * 杀死流星怪物
 */

func (this *star) KillStarMonster(c *context.Context) any {
	wave := c.GetInt32("waveID")
	monster := c.GetInt32("monsterID")
	if wave <= 0 || monster <= 0 {
		return errors.ErrArgEmpty
	}
	roleDoc := cache.GetRole(c.Player.Updater)
	roleData := roleDoc.All()
	starBuff, _ := roleData.GetStarBuff(c.Now())
	var newMonster []model.RoleStarBuffMonster
	var curMonster model.RoleStarBuffMonster
	for _, v := range starBuff.Monster {
		if v.WaveID == wave && v.Mid == monster {
			curMonster = v
		} else {
			newMonster = append(newMonster, model.RoleStarBuffMonster{})
		}
	}
	for _, v := range curMonster.Reward {
		c.Player.Add(v.Id, v.Num)
	}
	roleDoc.Set("StarBuff", starBuff)
	return nil
}

/**
 * @name clearMonster
 * 清空流星怪物
 */

func (this *star) ClearMonster(c *context.Context) any {

	roleDoc := cache.GetRole(c.Player.Updater)
	roleData := roleDoc.All()
	starBuff, _ := roleData.GetStarBuff(c.Now())
	starBuff.Monster = []model.RoleStarBuffMonster{}

	roleDoc.Set("StarBuff", starBuff)
	return nil
}
